import 'package:casdon/common/state/common_net_status.dart';
import 'package:casdon/core/extentions/datetime_extern.dart';
import 'package:casdon/core/extentions/string_validation.dart';
import 'package:casdon/core/logger/log.dart';
import 'package:casdon/core/network/business_exception.dart';
import 'package:casdon/core/utils/toast_utils.dart';
import 'package:casdon/modules/me/data/api/service_post_order_api.dart';
import 'package:casdon/modules/me/data/api/service_product_list_api.dart';
import 'package:casdon/modules/me/domain/states/service_post_order_satate.dart';
import 'package:casdon/modules/me/domain/usecase/service_post_order_usecase.dart';
import 'package:casdon/modules/me/domain/usecase/service_save_orderId_usecase.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:fluttertoast/fluttertoast.dart';

enum FormStatus { initial, submitting, success, failure }

class ServicePostOrderNotifier extends StateNotifier<ServicePostOrderState> {
  final Ref ref;
  final args;
  ServicePostOrder _postData = ServicePostOrder.initial();

  bool _hasProduct = false;
  bool _hasExpectTime = false;
  bool _hasContactName = false;
  bool _hasPhone = false;
  bool _hasLocation = false;
  bool _hasAddress = false;
  bool _hasMemo = false;
  bool _hasChannel = false;
  bool _hasBuyDate = false;
  bool _hasOrderNum = false;

  ServicePostOrderNotifier(this.ref, this.args)
    : super(ServicePostOrderState.idle());
  @override
  void dispose() {
    Log.d("ServicePostOrderNotifier 释放");
    super.dispose();
  }

  void updateProduct(ServiceProduct value) {
    _hasProduct = true;
    final product = Product(name: value.name, productNumber: value.number);
    final productGroup = ProductGroup(name: value.groupIdName);
    final productModel = ProductModel(name: value.moduleName);

    final productLine = _postData.productLines.first.copyWith(
      product: product,
      productGroup: productGroup,
      productModel: productModel,
    );
    state = state.copyWith(
      status: CommonNetStatus.idle,
      product: '${value.groupIdName}${value.name}',
    );
    _postData = _postData.copyWith(productLines: [productLine]);
  }

  void updateExpectTime(DateTime value) {
    _hasExpectTime = true;

    state = state.copyWith(
      status: CommonNetStatus.idle,
      expectTime: value.formatWeekDate(),
    );
    _postData = _postData.copyWith(
      expectArriveTime: value.formattedBeijingTime('yyyy/MM/dd'),
    );
  }

  void updateContactName(String value) {
    value.isEmpty ? _hasContactName = false : _hasContactName = true;
    state = state.copyWith(status: CommonNetStatus.idle, contact: value);
    _postData = _postData.copyWith(contact: value);
  }

  void updateContactPhone(String value) {
    value.isEmpty ? _hasPhone = false : _hasPhone = true;
    state = state.copyWith(status: CommonNetStatus.idle, phone: value);
    _postData = _postData.copyWith(phone: value);
  }

  void updateLocation(String location) {
    location.isEmpty ? _hasLocation = false : _hasLocation = true;
    state = state.copyWith(status: CommonNetStatus.idle, location: location);
  }

  void updateProvince(String code, String name) {
    final p = Province.initial().copyWith(code: code, name: name);
    _postData = _postData.copyWith(province: p);
  }

  void updateCity(String code, String name) {
    final c = City.initial().copyWith(code: code, name: name);
    _postData = _postData.copyWith(city: c);
  }

  void updateCounty(String code, String name) {
    final c = County.initial().copyWith(code: code, name: name);
    _postData = _postData.copyWith(county: c);
  }

  void updateAddress(String value) {
    value.isEmpty ? _hasAddress = false : _hasAddress = true;
    state = state.copyWith(status: CommonNetStatus.idle, address: value);
    _postData = _postData.copyWith(address: value);
  }

  void updateMemo(String value) {
    value.isEmpty ? _hasMemo = false : _hasMemo = true;
    state = state.copyWith(status: CommonNetStatus.idle, memo: value);
    _postData = _postData.copyWith(memo: value);
  }

  void updateChannel(String value) {
    value.isEmpty ? _hasChannel = false : _hasChannel = true;
    state = state.copyWith(status: CommonNetStatus.idle, channel: value);
    final sc = SalesChannel.initial().copyWith(name: value);
    _postData = _postData.copyWith(salesChannel: sc);
  }

  void updateBuyDate(DateTime value) {
    _hasBuyDate = true;
    state = state.copyWith(
      status: CommonNetStatus.idle,
      buyDate: value.formattedBeijingTime('yyyy/MM/dd'),
    );
    final productLine = _postData.productLines.first.copyWith(
      buyDate: value.formattedBeijingTime('yyyy/MM/dd'),
    );
    _postData = _postData.copyWith(productLines: [productLine]);
  }

  void updateOrderNumber(String value) {
    if (value.isEmpty) {
      _hasOrderNum = false;
    } else {
      _hasOrderNum = true;
    }

    state = state.copyWith(status: CommonNetStatus.idle, orderNum: value);
    _postData = _postData.copyWith(orderNumber: value);
  }

  Future<void> submit() async {
    state = state.copyWith(status: CommonNetStatus.idle, msg: "");
    if (!_hasProduct) {
      // state = state.copyWith(status: CommonNetStatus.failure, msg: "未选择产品");
      ToastUtil.show("未选择产品");
      return;
    }

    if (!_hasExpectTime) {
      // state = state.copyWith(status: CommonNetStatus.failure, msg: "未选择期望服务时间");
      ToastUtil.show("未选择期望服务时间");
      return;
    }

    if (!_hasContactName) {
      // state = state.copyWith(status: CommonNetStatus.failure, msg: "未输入联系人");
      ToastUtil.show("未输入联系人");
      return;
    }

    if (!_hasPhone) {
      // state = state.copyWith(status: CommonNetStatus.failure, msg: "未输入联系电话");
      ToastUtil.show("未输入联系电话");
      return;
    }

    if (!state.phone!.isPhoneNum()) {
      // state = state.copyWith(status: CommonNetStatus.failure, msg: "联系电话错误");
      ToastUtil.show("联系电话错误");
      return;
    }

    if (!_hasLocation) {
      // state = state.copyWith(status: CommonNetStatus.failure, msg: "未选择所在地区");
      ToastUtil.show("未选择所在地区");
      return;
    }

    if (!_hasAddress) {
      // state = state.copyWith(status: CommonNetStatus.failure, msg: "未输入详细地址");
      ToastUtil.show("未输入详细地址");
      return;
    }

    if (!_hasMemo) {
      // state = state.copyWith(status: CommonNetStatus.failure, msg: "未输入反馈内容");
      ToastUtil.show("未输入反馈内容");
      return;
    }

    if (!_hasChannel) {
      // state = state.copyWith(status: CommonNetStatus.failure, msg: "未选择购买渠道");
      ToastUtil.show("未选择购买渠道");
      return;
    }

    if (!_hasBuyDate) {
      // state = state.copyWith(status: CommonNetStatus.failure, msg: "未输入购买日期");
      ToastUtil.show("未输入购买日期");
      return;
    }

    if (!_hasOrderNum) {
      // state = state.copyWith(status: CommonNetStatus.failure, msg: "未输入订单号");
      ToastUtil.show("未输入订单号");
      return;
    }

    state = state.copyWith(status: CommonNetStatus.loading, msg: "");
    _postData = _postData.copyWith(type: args["type"] ?? 1);
    _postData = _postData.copyWith(serviceCategory: args["category"] ?? 3);
    try {
      final ret = await ref
          .read(servicePostOrderUsecaseProvider)
          .execute(_postData);
      Log.i(ret.toString());
      saveOrderReqId(orderReqId: ret.toString());
    } on BusinessException catch (e) {
      state = state.copyWith(status: CommonNetStatus.failure, msg: e.msg);
      Log.e("报装提交失败", e, StackTrace.current);
    } catch (e) {
      state = state.copyWith(status: CommonNetStatus.failure, msg: "");
      Log.e("报装提交失败", e, StackTrace.current);
    }
  }

  void saveOrderReqId({required String orderReqId}) async {
    try {
      final _ = await ref
          .read(serviceSaveOrderidUsecaseProvider)
          .execute(orderReqId);
      state = state.copyWith(status: CommonNetStatus.success, msg: "提交成功");
    } on BusinessException catch (e) {
      state = state.copyWith(status: CommonNetStatus.failure, msg: e.msg);
      Log.e("报装提交失败", e, StackTrace.current);
    } catch (e) {
      state = state.copyWith(status: CommonNetStatus.failure, msg: "$e");
      Log.e("报装提交失败", e, StackTrace.current);
    }
  }
}

final servicePostOrderNotifierProvider =
    AutoDisposeStateNotifierProvider.family<
      ServicePostOrderNotifier,
      ServicePostOrderState,
      Map<String, dynamic>
    >((ref, args) {
      return ServicePostOrderNotifier(ref, args);
    });
